/* eslint-disable */
// @ts-ignore
// import TweenMax from './TweenMax.min.js'
import { TweenMax, Sine, TweenLite } from 'gsap'

const resolution = (window as any).devicePixelRatio || 1
// const Sine = (window as any).Sine
// const TweenLite = (window as any).TweenLite

let vw: number = 0,
  vh: number = 0

function resizeCanvas(canvas: HTMLCanvasElement, context: any) {
  vw = 400
  vh = 160

  canvas.width = vw * resolution
  canvas.height = vh * resolution

  canvas.style.width = vw + 'px'
  canvas.style.height = vh + 'px'

  context.scale(resolution, resolution)
}

let resized = false

export const initWave = (id: string): void => {
  const canvas = document.getElementById(id) as HTMLCanvasElement
  const context = canvas.getContext('2d')
  const waves = [] as Array<any>

  resizeCanvas(canvas, context)
  if (context) {
    const gr1 = context.createLinearGradient(0, 0, 0, 200)
    gr1.addColorStop(0, 'rgba(152,142, 258, 0.02)')
    gr1.addColorStop(1, 'rgb(112,132, 228)')
    gr1.addColorStop(1, 'rgb(112,132, 228)')
    const gr2 = context.createLinearGradient(0, 0, 0, 200)
    gr2.addColorStop(0, 'rgba(152,142, 258, 0.01)')
    gr1.addColorStop(0.3, 'rgb(112,132, 228)')
    gr2.addColorStop(1, 'rgb(112,132, 228)')
    const wave1 = createWave(context as any, {
      amplitude: 50,
      duration: 1000 / 30,
      fillStyle: gr1,
      frequency: 2.5,
      width: vw,
      height: vh,
      segments: 100,
      waveHeight: vh * 0.25,
    })

    const wave2 = createWave(context as any, {
      amplitude: 100,
      duration: 1000 / 40,
      fillStyle: gr2,
      frequency: 1.5,
      width: vw,
      height: vh,
      segments: 100,
      waveHeight: vh * 0.25,
    })

    waves.push(wave1, wave2)

    TweenMax.to(waves, 10, {
      waveHeight: vh / 2,
      ease: Sine.easeInOut,
      repeat: -1,
      repeatDelay: 1,
      yoyo: true,
    })

    TweenMax.to(wave1, 6, {
      amplitude: 10,
      ease: Sine.easeInOut,
      repeat: -1,
      yoyo: true,
    })

    TweenMax.to(wave2, 7, {
      amplitude: 25,
      ease: Sine.easeInOut,
      repeat: -1,
      yoyo: true,
    })

    function tryDestroy(idDone: string) {
      const canvasDo = document.getElementById(idDone)
      if (!canvasDo) {
        //销毁
        window.removeEventListener('resize', resize)
        TweenLite.ticker.removeEventListener('tick', update)
      }
    }

    function resize() {
      tryDestroy(id)
      resized = true
    }

    window.addEventListener('resize', resize)

    TweenLite.ticker.addEventListener('tick', update)

    function update() {
      tryDestroy(id)
      let len = waves.length

      if (resized) {
        resizeCanvas(canvas, context)

        for (var i = 0; i < len; i++) {
          waves[i].resize(vw, vh)
        }

        resized = false
      }
      if (context) {
        context.clearRect(0, 0, vw, vh)
        context.globalCompositeOperation = 'soft-light'

        for (let i = 0; i < len; i++) {
          waves[i].draw(context)
        }
      }
    }
  }
}

function createWave(context: HTMLCanvasElement, options: any) {
  options = options || {}

  // API
  const wave = {
    // Properties
    amplitude: options.amplitude || 200,
    context: context,
    curviness: options.curviness || 0.75,
    duration: options.duration || 2,
    fillStyle: options.fillStyle || 'rgba(33,150,243,1)',
    frequency: options.frequency || 4,
    height: options.height || 600,
    points: [],
    segments: options.segments || 100,
    tweens: [],
    waveHeight: options.waveHeight || 300,
    width: options.width || 800,
    x: options.x || 0,
    y: options.y || 0,

    // Methods
    init: init,
    resize: resize,
    draw: draw,
    kill: kill,
  }

  init()

  function kill() {
    let tweens = wave.tweens
    let len = tweens.length

    for (var i = 0; i < len; i++) {
      ;(tweens[i] as any).kill()
    }

    tweens.length = 0
    wave.points.length = 0
  }

  function init() {
    kill()

    let segments = wave.segments
    let interval = wave.width / segments

    for (var i = 0; i <= segments; i++) {
      const norm = i / segments
      const point: any = {
        x: wave.x + i * interval,
        y: 1,
      }

      const tween = TweenMax.to(point, wave.duration, {
        y: -1,
        repeat: -1,
        yoyo: true,
        ease: Sine.easeInOut,
      }).progress(norm * wave.frequency) as never

      wave.tweens.push(tween)
      wave.points.push(point as never)
    }
  }

  function draw(context: any) {
    const points = wave.points as Array<any>
    const len = points.length

    const startY = wave.waveHeight
    let height = wave.amplitude / 2

    context.beginPath()
    context.moveTo(points[0].x, startY + points[0].y * height)

    for (var i = 1; i < len; i++) {
      let point = points[i]
      context.lineTo(point.x, startY + point.y * height)
    }

    context.lineTo(wave.x + wave.width, wave.y + wave.height)
    context.lineTo(wave.x, wave.y + wave.height)
    context.closePath()
    context.fillStyle = wave.fillStyle
    context.fill()
  }

  function resize(width: number, height: number) {
    wave.width = width
    wave.height = height

    let points = wave.points
    let len = points.length
    let interval = wave.width / wave.segments

    for (var i = 0; i < len; i++) {
      const point = points[i] as any
      point.x = wave.x + i * interval
    }
  }

  return wave
}
